﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using HYRevitCode.FormUtility;

namespace HYView
{
	public class FloorSelectManager
	{
		public static string CommandName
		{
			get
			{
				return FloorSelectManager.m_strCommandName;
			}
			set
			{
				FloorSelectManager.m_strCommandName = value;
			}
		}

		public static List<ViewPlan> GetAllFloorViewPlan(Autodesk.Revit.DB.Document doc)
		{
			List<Level> sortLevels = FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			List<ViewPlan> list = new List<ViewPlan>();
			List<double> list2 = new List<double>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)))
			{
				ViewPlan viewPlan = element as ViewPlan;
				if (viewPlan != null && (int)viewPlan.ViewType == 1 && viewPlan.GenLevel != null)
				{
					list2.Add(viewPlan.GenLevel.Elevation);
					list.Add(viewPlan);
				}
			}
			List<ViewPlan> list3 = new List<ViewPlan>();
			for (int i = 0; i < sortLevels.Count; i++)
			{
				for (int j = 0; j < list2.Count; j++)
				{
					if (FloorSelectManager.IsEqual(sortLevels[i].Elevation, list2[j]))
					{
						list3.Add(list[j]);
					}
				}
			}
			return list3;
		}

		public static List<ViewPlan> GetAllFireAreaViewPlan(Autodesk.Revit.DB.Document doc)
		{
			List<Level> sortLevels = FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			List<ViewPlan> list = new List<ViewPlan>();
			List<double> list2 = new List<double>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)))
			{
				ViewPlan viewPlan = element as ViewPlan;
				if (viewPlan != null && (int)viewPlan.ViewType == 116 && viewPlan.GenLevel != null && viewPlan.AreaScheme.Name.Contains("防火分区面积"))
				{
					list2.Add(viewPlan.GenLevel.Elevation);
					list.Add(viewPlan);
				}
			}
			List<ViewPlan> list3 = new List<ViewPlan>();
			for (int i = 0; i < sortLevels.Count; i++)
			{
				for (int j = 0; j < list2.Count; j++)
				{
					if (FloorSelectManager.IsEqual(sortLevels[i].Elevation, list2[j]))
					{
						list3.Add(list[j]);
					}
				}
			}
			return list3;
		}

		public static bool SelectFloorViewPlans(Autodesk.Revit.DB.Document doc, ref List<ViewPlan> selectFloorLevels, FloorSelectManager.IfViewPlanCanUse inpuDel = null)
		{
			if (inpuDel == null)
			{
				inpuDel = new FloorSelectManager.IfViewPlanCanUse(FloorSelectManager.DefaultCheckViewPlan);
			}
			List<Level> sortLevels = FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			List<ViewPlan> list = new List<ViewPlan>();
			List<double> list2 = new List<double>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)))
			{
				ViewPlan viewPlan = element as ViewPlan;
				if (viewPlan != null && inpuDel(viewPlan) && viewPlan.GenLevel != null)
				{
					list2.Add(viewPlan.GenLevel.Elevation);
					list.Add(viewPlan);
				}
			}
			List<ViewPlan> list3 = new List<ViewPlan>();
			for (int i = 0; i < sortLevels.Count; i++)
			{
				for (int j = 0; j < list2.Count; j++)
				{
					if (FloorSelectManager.IsEqual(sortLevels[i].Elevation, list2[j]))
					{
						list3.Add(list[j]);
					}
				}
			}
			List<ViewPlan> list4 = list3.Distinct(new FloorSelectManager.LevelEqualityComparer()).ToList<ViewPlan>();
			SelectFloorForm selectFloorForm = new SelectFloorForm((from l in list4
			select l.GenLevel).ToList<Level>());
			if (selectFloorForm.ShowDialog() != DialogResult.OK)
			{
				return false;
			}
			foreach (int index in selectFloorForm.SelectedViewIndexs())
			{
				selectFloorLevels.Add(list4[index]);
			}
			return true;
		}

		public static bool SelectAllFloorViewPlans(Autodesk.Revit.DB.Document doc, ref List<ViewPlan> selectFloorLevels)
		{
			FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			List<ViewPlan> list = new List<ViewPlan>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)))
			{
				ViewPlan viewPlan = element as ViewPlan;
				if (viewPlan != null && (int)viewPlan.ViewType == 1 && viewPlan.GenLevel != null && !viewPlan.Name.Contains(FloorSelectManager.m_strDelName))
				{
					list.Add(viewPlan);
				}
			}
			SelectFloorForm dlg = new SelectFloorForm();
			string pathName = doc.PathName;
			list.ForEach(delegate(ViewPlan v)
			{
				dlg.ChklViewOrLevel.Items.Add(v.Name);
			});
			SelectFloorUtility.ReadSelectFloorsForm(FloorSelectManager.m_strCommandName, pathName, dlg.ChklViewOrLevel);
			if (dlg.ShowDialog() != DialogResult.OK)
			{
				return false;
			}
			SelectFloorUtility.WriteSelectFloorsToFile(FloorSelectManager.m_strCommandName, pathName, dlg.ChklViewOrLevel);
			foreach (int index in dlg.SelectedViewIndexs())
			{
				selectFloorLevels.Add(list[index]);
			}
			return true;
		}

		public static bool SelectFloorLevels(Autodesk.Revit.DB.Document doc, ref List<Level> selectFloorLevels)
		{
			List<ViewPlan> list = new List<ViewPlan>();
			if (!FloorSelectManager.SelectFloors(doc, ref list, null))
			{
				return false;
			}
			foreach (ViewPlan viewPlan in list)
			{
				selectFloorLevels.Add(viewPlan.GenLevel);
			}
			return true;
		}

		public static bool SelectFloors(Autodesk.Revit.DB.Document doc, ref List<ViewPlan> selectFloors, string strFormCaption = null)
		{
			List<Level> levels = FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			List<ViewPlan> list = new List<ViewPlan>();
			List<double> list2 = new List<double>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)))
			{
				ViewPlan viewPlan = element as ViewPlan;
				if (viewPlan != null && (int)viewPlan.ViewType == 1 && viewPlan.GenLevel != null && !viewPlan.Name.Contains(FloorSelectManager.m_strCommandName))
				{
					list2.Add(viewPlan.GenLevel.Elevation);
					list.Add(viewPlan);
				}
			}
			int i = 0;
			List<ViewPlan> list3 = new List<ViewPlan>();
			Predicate<double> ss9__1 = null;
			while (i < levels.Count)
			{
				List<double> list4 = list2;
				Predicate<double> match;
				if ((match = ss9__1) == null)
				{
					match = (ss9__1 = ((double item) => FloorSelectManager.IsEqual(item, levels[i].Elevation)));
				}
				int num = list4.FindIndex(match);
				int j;
				if (num == -1)
				{
					levels.RemoveAt(i);
					j = i - 1;
					i = j;
				}
				else
				{
					list3.Add(list[num]);
				}
				j = i + 1;
				i = j;
			}
			SelectFloorForm dlg = new SelectFloorForm();
			string pathName = doc.PathName;
			list3.ForEach(delegate(ViewPlan v)
			{
				dlg.ChklViewOrLevel.Items.Add(v.Name);
			});
			SelectFloorUtility.ReadSelectFloorsForm(FloorSelectManager.m_strCommandName, pathName, dlg.ChklViewOrLevel);
			dlg.strFormCaption = strFormCaption;
			if (dlg.ShowDialog() != DialogResult.OK)
			{
				return false;
			}
			SelectFloorUtility.WriteSelectFloorsToFile(FloorSelectManager.m_strCommandName, pathName, dlg.ChklViewOrLevel);
			foreach (int index in dlg.SelectedViewIndexs())
			{
				selectFloors.Add(list3[index]);
			}
			return true;
		}

		public static List<Level> GetSortLevels(Autodesk.Revit.DB.Document doc, double bottom, double top)
		{
			List<Level> list = new List<Level>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Level)).ToElements())
			{
				Level level = element as Level;
				double elevation = level.Elevation;
				if (elevation >= bottom && elevation <= top)
				{
					list.Add(level);
				}
			}
			list.Sort(new FloorSelectManager.LevelComparer());
			return list;
		}

		public static bool SelectLevel(Autodesk.Revit.DB.Document doc, ref List<Level> selectLevels, string strFormCaption = null)
		{
			List<Level> sortLevels = FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			SelectFloorForm selectFloorForm = new SelectFloorForm(sortLevels);
			selectFloorForm.strFormCaption = strFormCaption;
			if (selectFloorForm.ShowDialog() != DialogResult.OK)
			{
				return false;
			}
			foreach (int index in selectFloorForm.SelectedViewIndexs())
			{
				selectLevels.Add(sortLevels[index]);
			}
			return true;
		}

		private static bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		private static bool IsEqual(double val1, double val2)
		{
			return !FloorSelectManager.LessThan(val1, val2) && !FloorSelectManager.LessThan(val2, val1);
		}

		private static bool DefaultCheckViewPlan(ViewPlan inputPlan)
		{
            return (int)inputPlan.ViewType == 1;
		}

		private static string m_strDelName = "留洞图";

		private static string m_strCommandName = null;

		private const double _epsDouble = 1E-09;

		public delegate bool IfViewPlanCanUse(ViewPlan inputViewPlan);

		private class LevelComparer : IComparer<Level>
		{
			public int Compare(Level x, Level y)
			{
				return x.Elevation.CompareTo(y.Elevation);
			}
		}

		private class LevelEqualityComparer : IEqualityComparer<ViewPlan>
		{
			public bool Equals(ViewPlan ele1, ViewPlan ele2)
			{
				return ele1.GenLevel.Elevation == ele2.GenLevel.Elevation;
			}

			public int GetHashCode(ViewPlan obj)
			{
				return obj.ToString().GetHashCode();
			}
		}
	}
}
